package com.crm.system.service.impl.orderManager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DhPageInfo;
import com.crm.common.util.CommonUtils;
import com.crm.model.dto.InsertCustomerProductOrderCallable;
import com.crm.model.entity.sys.ImportExport;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.qo.orderManager.ExportOrderProductQO;
import com.crm.model.qo.sys.ImportFailureLogQO;
import com.crm.model.vo.orderManager.CustomerProductOrderImportVO;
import com.crm.model.vo.orderManager.OrderProductPriceVO;
import com.crm.model.vo.sys.ImportFailureLogVO;
import com.crm.service.contractManager.CustomerContractDbService;
import com.crm.service.customerManager.CustomerDbService;
import com.crm.service.orderManager.CustomerProductOrderDbService;
import com.crm.service.orderManager.CustomerProductOrderDetailDbService;
import com.crm.service.productManager.CustomerMemberProductDbService;
import com.crm.service.productManager.CustomerProductDbService;
import com.crm.service.returnMoney.FinishOrderDBservice;
import com.crm.service.sys.ImportExportDbService;
import com.crm.service.sys.ImportFailureLogDbService;
import com.crm.service.sys.UserInfoDbService;
import com.crm.service.sys.permissionManagement.SysCompanyDbService;
import com.crm.system.service.orderManager.CustomerProductOrderImportService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * @ Author ：pym
 * @ Date   ：2021/6/1 9:54
 */
@Service
@Slf4j
public class CustomerProductOrderImportServiceImpl implements CustomerProductOrderImportService {
    @Autowired
    private CustomerProductOrderDbService customerProductOrderDbService;
    @Autowired
    private CustomerDbService customerDbService;
    @Autowired
    private CustomerContractDbService customerContractDbService;
    @Autowired
    private ImportExportDbService importExportDbService;
    @Autowired
    private ImportFailureLogDbService importFailureLogDbService;
    @Autowired
    private CustomerMemberProductDbService memberProductDbService;
    @Autowired
    private CustomerProductDbService customerProductDbService;
    @Autowired
    private CustomerProductOrderDetailDbService customerProductOrderDetailDbService;
    @Autowired
    private FinishOrderDBservice finishOrderDBservice;
    @Autowired
    private UserInfoDbService userInfoDbService;
    @Autowired
    private SysCompanyDbService sysCompanyDbService;

    /**
     * 订单导入
     * @Author pym
     * @Date  2021/6/1 16:57
     * @param list 订单集合
     * @return {@link {com.alibaba.fastjson.JSONObject}}
     */
    @Override
    public JSONObject importCustomerProductOrder(List<CustomerProductOrderImportVO> list) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();
        //返回的结果集
        JSONObject jsonObject = new JSONObject();
        int count = 100;                   //一个线程处理100条数据
        int listSize = list.size();        //数据集合大小
        int runSize = (listSize/count)+1;  //开启的线程数
        List<CustomerProductOrderImportVO> newList = null;       //存放每个线程的执行数据
        ExecutorService executor = Executors.newCachedThreadPool();
        //创建两个个计数器
        CountDownLatch begin = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(runSize);
        List<FutureTask<JSONObject>> taskList = new ArrayList<FutureTask<JSONObject>>();
        for (int i = 0; i < runSize ; i++) {
            //计算每个线程执行的数据
            if ((i + 1) == runSize) {
                int startIndex = (i * count);
                int endIndex = list.size();
                newList = list.subList(startIndex, endIndex);
            } else {
                int startIndex = (i * count);
                int endIndex = (i + 1) * count;
                newList = list.subList(startIndex, endIndex);
            }
            FutureTask<JSONObject> futureTask = new FutureTask(
                    new InsertCustomerProductOrderCallable(customerProductOrderDbService, importFailureLogDbService,
                            customerDbService, customerContractDbService, memberProductDbService, customerProductDbService,
                            customerProductOrderDetailDbService, finishOrderDBservice, userInfoDbService,
                            sysCompanyDbService, newList, begin, end, i));
            taskList.add(futureTask);
            executor.submit(futureTask);//submit返回一个Future，代表了即将要返回的结果
        }
        // 关闭线程池
        executor.shutdown();
        return getJsonObject(userAccount, jsonObject, taskList);
    }

    /**
     * 获取json对象
     * @Author pym
     * @Date  2021/6/2 15:38
     * @param userAccount 账号信息
     * @param jsonObject json对象
     * @param taskList
     * @return {@link {com.alibaba.fastjson.JSONObject}}
     */
    private JSONObject getJsonObject(UserAccount userAccount, JSONObject jsonObject, List<FutureTask<JSONObject>> taskList) {
        //导入数量
        int importNum = 0;
        //重复的行数
        List<Integer> repeatIdStr = new ArrayList();
        //失败行数
        List<Integer> importFailIdStr = new ArrayList();
        //合同不存在行数
        List<Integer> contractNotExist = new ArrayList();
        //客户不存在行数
        List<Integer> customerNotExist = new ArrayList();
        //只导入回款状态为已回款并且订单状态为生效中或者已结束的订单，其它的订单需手工录入
        List<Integer> otherOrders = new ArrayList();
        List<Integer> ownerNull = new ArrayList();//所有人不存在
        for (int i = 0; i < taskList.size(); i++) {
            try {
                // FutureTask的get方法会自动阻塞,直到获取计算结果为止
                JSONObject jsonObj = taskList.get(i).get();
                importNum = importNum + jsonObj.getInteger("importNum");
                repeatIdStr = getLineNumberList(repeatIdStr, jsonObj, i, "repeatIdStr");
                importFailIdStr = getLineNumberList(importFailIdStr, jsonObj, i, "importFailIdStr");
                contractNotExist = getLineNumberList(contractNotExist, jsonObj, i, "contractNotExist");
                customerNotExist = getLineNumberList(customerNotExist, jsonObj, i, "customerNotExist");
                otherOrders = getLineNumberList(otherOrders, jsonObj, i, "otherOrders");
                ownerNull = getLineNumberList(ownerNull, jsonObj, i, "ownerNull");
            } catch (Exception e) {
                log.error("CustomerProductOrderImportServiceImpl importCustomerProductOrder error:", e);
            }
        }
        jsonObject.put("importNum", importNum);
        jsonObject.put("repeatIdStr", repeatIdStr);
        jsonObject.put("importFailIdStr", importFailIdStr);
        jsonObject.put("contractNotExist", contractNotExist);
        jsonObject.put("customerNotExist", customerNotExist);
        jsonObject.put("otherOrders", otherOrders);
        jsonObject.put("ownerNull", ownerNull);
        //插入订单导入记录
        if (importNum > 0) {
            ImportExport importExport = new ImportExport();
            importExport.setImportExportId(CommonUtils.getGUID());
            importExport.setOperatePeopleId(userAccount.getAccountId());
            importExport.setOperateTime(new Date());
            importExport.setOperateQuantity(importNum);
            importExport.setOperateType("3");
            importExport.setOperateWay("1");
            importExportDbService.insert(importExport);
        }
        return jsonObject;
    }

    /**
     * 获取行数集合
     * @Author pym
     * @Date  2021/6/2 14:26
     * @param jsonObject json对象
     * @param i 循环
     * @param key json对象key
     * @return {@link {java.util.List<java.lang.Integer>}}
     */
    private List<Integer> getLineNumberList(List<Integer> lineNumberList, JSONObject jsonObject, int i, String  key){
        JSONArray lineNumberArray = jsonObject.getJSONArray(key);
        for (int j = 0; j < lineNumberArray.size(); j++){
            int lineNumber = Integer.parseInt(lineNumberArray.get(j).toString());
            lineNumberList.add(lineNumber + i *100);
        }
        return lineNumberList;
    }

    /**
     * 导入失败数据列表
     * @Author pym
     * @Date  2021/6/8 15:04
     * @param pageIndex -页码
     * @param pageSize -分页大小
     * @param importFailureLogQO -查询条件
     * @param sortName -排序列名字
     * @param sortOrder -排序规则(asc/desc)
     * @return {@link {com.crm.common.model.DhPageInfo<com.crm.model.vo.sys.ImportFailureLogVO>}}
     */
    @Override
    public DhPageInfo<ImportFailureLogVO> selectOrderImportFailedDataList(Integer pageIndex, Integer pageSize,
                                                                     ImportFailureLogQO importFailureLogQO,
                                                                     String sortName, String sortOrder) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();
        List<ImportFailureLogVO> importFailedDataList = new ArrayList<ImportFailureLogVO>();
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }
        if (CommonUtils.isAdmin(userAccount.getUserId())) { //超级管理员
            importFailedDataList = importFailureLogDbService.selectOrderImportFailedDataList(importFailureLogQO, null);
        } else if (1 == importFailureLogQO.getQx()){
            importFailureLogQO.setCompanyId(userAccount.getCompanyId());
            importFailedDataList = importFailureLogDbService.selectOrderImportFailedDataList(importFailureLogQO, null);
        }else {
            importFailedDataList = importFailureLogDbService.selectOrderImportFailedDataList(importFailureLogQO, userAccount.getAccountId());
        }
        PageInfo<ImportFailureLogVO> pageInfo = new PageInfo<ImportFailureLogVO>(importFailedDataList);
        return new DhPageInfo<ImportFailureLogVO>(pageInfo, importFailedDataList);
    }

    /**
     * 获取产品名称表头
     * @Author pym
     * @Date  2021/8/13 10:36
     * @param type 类型 memberNew：会员新建订单；membershipRenewal：会员续费订单；course：课程订单；refund：退款
     * @param exportOrderProductQO 筛选条件
     * @param companyId 公司id
     * @return {@link {java.util.List<java.lang.String>}}
     */
    @Override
    public List<String> getProductNameList(String type, ExportOrderProductQO exportOrderProductQO, String companyId) {
        List<String> productNameList = null;
        if ("refund".equals(type)) {
            productNameList = customerProductOrderDbService.getRefundProductNameList(exportOrderProductQO, companyId);
        } else {
            productNameList = customerProductOrderDbService.getProductNameList(type, exportOrderProductQO, companyId);
        }
        return productNameList;
    }

    /**
     * 获取产品名称和价格
     * @Author pym
     * @Date  2021/8/13 10:37
     * @param type 类型 memberNew：会员新建订单；membershipRenewal：会员续费订单；course：课程订单；refund：
     * @param exportOrderProductQO 筛选条件
     * @param companyId 公司id
     * @return {@link {java.util.List<com.crm.model.vo.orderManager.OrderProductPriceVO>}}
     */
    @Override
    public List<OrderProductPriceVO> getProductNameAndPriceList(String type, ExportOrderProductQO exportOrderProductQO, String companyId) {
        List<OrderProductPriceVO> productNameAndPriceList = null;
        if ("refund".equals(type)) {
            productNameAndPriceList = customerProductOrderDbService.getRefundProductNameAndPriceList(exportOrderProductQO, companyId);
        } else {
            productNameAndPriceList = customerProductOrderDbService.getProductNameAndPriceList(type, exportOrderProductQO, companyId);
        }
        return productNameAndPriceList;
    }
}
